package cn.edu.zime.tjh.iotapp.api;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;

import java.io.File;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.ResponseBody;
import okio.BufferedSource;

import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * API服务类，实现所有具体的后端API请求方法
 */
public class ApiService {
    private static final String TAG = "ApiService";
    
    // API端点常量
    private static final String ENDPOINT_LOGIN = "/auth/login";
    private static final String ENDPOINT_REGISTER = "/auth/register";
    private static final String ENDPOINT_RESET_PASSWORD = "/auth/reset-password";
    private static final String ENDPOINT_VERIFY_EMAIL = "/auth/verify-email";
    private static final String ENDPOINT_DETECT = "/detect";
    private static final String ENDPOINT_SENSOR_DATA = "/sensor/data";
    private static final String ENDPOINT_DEVICES = "/devices";
    
    // 单例模式
    private static ApiService instance;
    private final ApiClient apiClient;
    
    /**
     * 私有构造函数
     */
    public ApiService() {
        apiClient = ApiClient.getInstance();
    }
    
    /**
     * 获取ApiService单例
     */
    public static synchronized ApiService getInstance() {
        if (instance == null) {
            instance = new ApiService();
        }
        return instance;
    }
    
    /**
     * 测试API连接
     * 
     * @param callback 回调接口
     */
    public void testConnection(ApiCallback callback) {
        // 创建handler用于在主线程回调
        Handler handler = new Handler(Looper.getMainLooper());
        
        // 创建新线程执行网络请求
        new Thread(() -> {
            try {
                // 创建URL连接到服务器根目录下的apispec.json
                String serverUrl = ApiClient.getInstance().getBaseUrl() + "/apispec.json";
                URL url = new URL(serverUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(5000); // 5秒超时
                connection.setReadTimeout(5000);
                
                // 获取响应代码
                int responseCode = connection.getResponseCode();
                
                // 关闭连接
                connection.disconnect();
                
                // 创建简单的响应JSON
                JSONObject response = new JSONObject();
                response.put("status", "online");
                response.put("code", responseCode);
                
                // 在主线程中回调成功
                handler.post(() -> callback.onSuccess(response));
                
            } catch (Exception e) {
                // 在主线程中回调失败
                handler.post(() -> callback.onFailure(e.getMessage()));
            }
        }).start();
    }
    
    /**
     * 用户登录
     *
     * @param username 用户名
     * @param password 密码
     * @param callback 回调接口
     */
    public void login(String username, String password, ApiCallback callback) {
        try {
            JSONObject requestBody = new JSONObject();
            requestBody.put("username", username);
            requestBody.put("password", password);
            
            Log.d(TAG, "发送登录请求: " + ENDPOINT_LOGIN);
            Log.d(TAG, "请求体: " + requestBody.toString());
            
            apiClient.postJson(ENDPOINT_LOGIN, requestBody, callback);
        } catch (JSONException e) {
            Log.e(TAG, "创建登录请求失败: " + e.getMessage());
            callback.onFailure("创建请求数据失败: " + e.getMessage());
        }
    }
    /**
     * 获取注册用的邮箱验证码
     *
     * @param email    邮箱地址
     * @param callback 回调接口
     */
    public void getRegisterVerificationCode(String email, ApiCallback callback) {
        try {
            JSONObject requestBody = new JSONObject();
            requestBody.put("email", email);
            requestBody.put("purpose", "register");  // 目的是注册
            
            Log.d(TAG, "发送获取注册验证码请求: " + ENDPOINT_VERIFY_EMAIL);
            Log.d(TAG, "请求体: " + requestBody.toString());
            
            apiClient.postJson(ENDPOINT_VERIFY_EMAIL, requestBody, callback);
        } catch (JSONException e) {
            Log.e(TAG, "创建获取注册验证码请求失败: " + e.getMessage());
            callback.onFailure("创建请求数据失败: " + e.getMessage());
        }
    }


    /**
     * 用户注册
     *
     * @param registerParams 包含注册信息的JSON对象
     * @param callback 回调接口
     */
    public void register(JSONObject registerParams, ApiCallback callback) {
        try {
            Log.d(TAG, "发送注册请求: " + ENDPOINT_REGISTER);
            Log.d(TAG, "请求体: " + registerParams.toString());

            apiClient.postJson(ENDPOINT_REGISTER, registerParams, callback);
        } catch (Exception e) {
            Log.e(TAG, "创建注册请求失败: " + e.getMessage());
            callback.onFailure("创建请求数据失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取邮箱验证码（用于找回密码 - 第一阶段）
     *
     * @param email    邮箱地址
     * @param callback 回调接口
     */
    public void getVerificationCode(String email, ApiCallback callback) {
        try {
            JSONObject requestBody = new JSONObject();
            requestBody.put("email", email);
            
            Log.d(TAG, "发送获取验证码请求: " + ENDPOINT_RESET_PASSWORD);
            Log.d(TAG, "请求体: " + requestBody.toString());
            
            apiClient.postJson(ENDPOINT_RESET_PASSWORD, requestBody, callback);
        } catch (JSONException e) {
            Log.e(TAG, "创建获取验证码请求失败: " + e.getMessage());
            callback.onFailure("创建请求数据失败: " + e.getMessage());
        }
    }
    
    /**
     * 重置密码（第二阶段）
     *
     * @param email           邮箱地址
     * @param verificationCode 验证码
     * @param newPassword     新密码
     * @param callback        回调接口
     */
    public void resetPassword(String email, String verificationCode, String newPassword, ApiCallback callback) {
        try {
            JSONObject requestBody = new JSONObject();
            requestBody.put("email", email);
            requestBody.put("verification_code", verificationCode);
            requestBody.put("new_password", newPassword);
            
            Log.d(TAG, "发送重置密码请求: " + ENDPOINT_RESET_PASSWORD);
            Log.d(TAG, "请求体: " + requestBody.toString());
            
            apiClient.postJson(ENDPOINT_RESET_PASSWORD, requestBody, callback);
        } catch (JSONException e) {
            Log.e(TAG, "创建重置密码请求失败: " + e.getMessage());
            callback.onFailure("创建请求数据失败: " + e.getMessage());
        }
    }
    
    /**
     * 使用YOLO算法检测图像中的物体
     *
     * @param imageFile 包含要检测物体的图像文件
     * @param callback  回调接口
     */
    public void detectObjects(File imageFile, ApiCallback callback) {
        if (imageFile == null || !imageFile.exists()) {
            Log.e(TAG, "检测图像文件不存在或为空");
            callback.onFailure("图像文件不存在或无效");
            return;
        }

        Log.d(TAG, "准备上传图片进行检测，文件大小: " + (imageFile.length() / 1024) + "KB, 路径: " + imageFile.getAbsolutePath());
        
        try {
            // 验证文件可读
            if (!imageFile.canRead()) {
                Log.e(TAG, "图像文件不可读: " + imageFile.getAbsolutePath());
                callback.onFailure("图像文件不可读，请检查文件权限");
                return;
            }
            
            // 检查文件扩展名，确保是支持的图像格式
            String fileName = imageFile.getName().toLowerCase();
            if (!(fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") || 
                  fileName.endsWith(".png") || fileName.endsWith(".bmp"))) {
                Log.w(TAG, "文件扩展名可能不是支持的图像格式: " + fileName);
            }
            
            // 根据文件扩展名确定正确的MediaType
            MediaType mediaType;
            if (fileName.endsWith(".png")) {
                mediaType = MediaType.parse("image/png");
            } else if (fileName.endsWith(".bmp")) {
                mediaType = MediaType.parse("image/bmp");
            } else {
                // 默认假设为JPEG
                mediaType = MediaType.parse("image/jpeg");
            }
            
            // 创建请求体
            RequestBody requestFile = RequestBody.create(mediaType, imageFile);
            Log.d(TAG, "已创建RequestBody，MediaType: " + mediaType);
            
            // 创建MultipartBody
            MultipartBody.Builder builder = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("image", imageFile.getName(), requestFile);
                    
            // 添加其他可能的参数
            builder.addFormDataPart("confidence", "0.4");  // 置信度阈值降低一点，增加检测灵敏度
            builder.addFormDataPart("format", "json");     // 返回格式
            
            // 构建完整的多部分请求体
            RequestBody requestBody = builder.build();
            Log.d(TAG, "已创建完整的MultipartBody请求体");
            
            // 发送请求
            Log.d(TAG, "正在发送图像检测请求到: " + ENDPOINT_DETECT);
            
            // 创建封装的回调来添加额外的日志
            ApiCallback wrappedCallback = new ApiCallback() {
                @Override
                public void onSuccess(JSONObject response) {
                    Log.d(TAG, "检测请求成功返回，包含数据: " + (response != null));
                    // 转发到原始回调
                    callback.onSuccess(response);
                }

                @Override
                public void onFailure(String errorMessage) {
                    Log.e(TAG, "检测请求失败: " + errorMessage);
                    // 转发到原始回调
                    callback.onFailure(errorMessage);
                }
            };
            
            // 使用ApiClient发送请求
            ApiClient.getInstance().postMultipart(ENDPOINT_DETECT, requestBody, wrappedCallback);
            
        } catch (Exception e) {
            Log.e(TAG, "构建检测请求失败", e);
            callback.onFailure("构建检测请求失败: " + e.getMessage());
        }
    }
    
    /**
     * 查询检测历史详情
     *
     * @param detectionId 检测ID
     * @param callback    回调接口
     */
    public void getDetectionHistory(int detectionId, ApiCallback callback) {
        String endpoint = "/detect/history/" + detectionId;
        apiClient.get(endpoint, callback);
    }
    
    /**
     * 获取所有设备列表
     * 对应API: GET /api/devices/
     * 
     * @param callback 回调接口
     */
    public void getDeviceList(ApiCallback callback) {
        apiClient.get(ENDPOINT_DEVICES + "/", callback);
    }
    
    /**
     * 获取设备详情
     * 对应API: GET /api/devices/{device_id}
     * 
     * @param deviceId 设备ID
     * @param callback 回调接口
     */
    public void getDeviceDetail(String deviceId, ApiCallback callback) {
        apiClient.get(ENDPOINT_DEVICES + "/" + deviceId, callback);
    }
    
    /**
     * 添加设备 - 严格按照后端接口要求
     * 对应API: POST /api/devices
     * 
     * @param device_id 设备唯一标识 (必填)
     * @param device_name 设备名称 (必填)
     * @param device_type 设备类型 (选填)
     * @param device_info 设备附加信息 (选填)
     * @param device_web 设备Web页面地址 (选填)
     * @param image 设备图片的Base64编码 (选填)
     * @param device_status 设备状态 (选填，默认为"active")
     * @param callback 回调接口
     */
    public void addDevice(String device_id, String device_name, String device_type, 
                         String device_info, String device_web, String image, 
                         String device_status, ApiCallback callback) {
        try {
            // 创建符合后端API格式的请求体
            JSONObject requestBody = new JSONObject();
            
            // 必填字段
            requestBody.put("device_id", device_id);
            requestBody.put("device_name", device_name);
            
            // 选填字段，仅在非空时添加
            if (device_type != null && !device_type.isEmpty()) {
                requestBody.put("device_type", device_type);
            }
            
            // 状态字段，默认为"active"
            if (device_status != null && !device_status.isEmpty()) {
                requestBody.put("device_status", device_status);
            } else {
                requestBody.put("device_status", "active");
            }
            
            if (device_info != null && !device_info.isEmpty()) {
                requestBody.put("device_info", device_info);
            }
            
            if (device_web != null && !device_web.isEmpty()) {
                requestBody.put("device_web", device_web);
            }
            
            // 处理图片
            if (image != null && !image.isEmpty()) {
                // 如果是base64图像但没有前缀，添加前缀
                if (!image.startsWith("data:image") && !image.startsWith("http")) {
                    requestBody.put("image", "data:image/jpeg;base64," + image);
                } else {
                    requestBody.put("image", image);
                }
            }
            
            Log.d(TAG, "添加设备请求: " + device_id + ", " + device_name);
            
            // 发送请求
            apiClient.postJson(ENDPOINT_DEVICES, requestBody, callback);
        } catch (JSONException e) {
            Log.e(TAG, "构建设备添加请求失败: " + e.getMessage());
            callback.onFailure("构建请求失败: " + e.getMessage());
        }
    }

    /**
     * 删除设备
     * 对应API: DELETE /api/devices/{device_id}
     * 
     * @param device_id 设备ID
     * @param callback 回调接口
     */
    public void deleteDevice(String device_id, ApiCallback callback) {
        apiClient.delete(ENDPOINT_DEVICES + "/" + device_id, callback);
    }
    
    /**
     * 获取设备传感器数据历史
     * 
     * @param deviceId 设备ID
     * @param sensorType 传感器类型
     * @param hours 查询过去多少小时的数据
     * @param callback 回调接口
     */
    public void getDeviceSensorHistory(String deviceId, String sensorType, int hours, ApiCallback callback) {
        String url = "/sensor/history?device_id=" + deviceId;
        
        if (sensorType != null && !sensorType.isEmpty()) {
            url += "&type=" + sensorType;
        }
        
        url += "&hours=" + hours;
        
        apiClient.get(url, callback);
    }

    /**
     * 提交传感器数据
     * @param data 包含传感器类型、数值和警报级别的JSON对象
     * @param callback 回调接口
     */
    public void submitSensorData(JSONObject data, ApiCallback callback) {
        try {
            Log.d(TAG, "正在提交传感器数据: " + data.toString());
            apiClient.postJson(ENDPOINT_SENSOR_DATA, data, callback);
        } catch (Exception e) {
            Log.e(TAG, "提交传感器数据时出错: " + e.getMessage());
            callback.onFailure("提交传感器数据时出错: " + e.getMessage());
        }
    }

    /**
     * 发送聊天消息到DeepSeek流式API
     * 
     * @param userMessage 用户消息内容
     * @param callback 流式回调接口
     */
    public void sendChatMessage(String userMessage, StreamingChatCallback callback) {
        try {
            // 创建聊天请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("model", "deepseek-chat");
            
            // 创建消息数组
            JSONArray messagesArray = new JSONArray();
            
            // 添加系统消息
            JSONObject systemMessage = new JSONObject();
            systemMessage.put("role", "system");
            systemMessage.put("content", "你是一个有用的助手，用中文回答问题。");
            messagesArray.put(systemMessage);
            
            // 添加用户消息
            JSONObject userMessageObj = new JSONObject();
            userMessageObj.put("role", "user");
            userMessageObj.put("content", userMessage);
            messagesArray.put(userMessageObj);
            
            // 设置消息数组和流式标志
            requestBody.put("messages", messagesArray);
            requestBody.put("stream", true);
            
            // 创建请求
            Request request = new Request.Builder()
                .url("https://api.deepseek.com/chat/completions")
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization", "Bearer sk-746458575c794f43ba72e1404aba54b8")
                .post(RequestBody.create(
                    MediaType.parse("application/json"), 
                    requestBody.toString())
                )
                .build();
            
            // 发送请求并处理流式响应
            OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();
                
            client.newCall(request).enqueue(new Callback() {
                StringBuilder fullResponse = new StringBuilder();
                
                @Override
                public void onFailure(Call call, IOException e) {
                    Log.e(TAG, "聊天请求失败", e);
                    // 在主线程中回调错误
                    new Handler(Looper.getMainLooper()).post(() -> {
                        callback.onError("请求失败: " + e.getMessage());
                    });
                }
                
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if (!response.isSuccessful()) {
                        Log.e(TAG, "聊天请求响应错误，状态码: " + response.code());
                        String errorBody = response.body() != null ? response.body().string() : "未知错误";
                        
                        // 在主线程中回调错误
                        new Handler(Looper.getMainLooper()).post(() -> {
                            callback.onError("请求错误，状态码: " + response.code() + ", " + errorBody);
                        });
                        return;
                    }
                    
                    try (ResponseBody responseBody = response.body()) {
                        if (responseBody == null) {
                            Log.e(TAG, "响应体为空");
                            new Handler(Looper.getMainLooper()).post(() -> {
                                callback.onError("响应体为空");
                            });
                            return;
                        }
                        
                        // 用于流式处理数据的BufferedSource
                        BufferedSource source = responseBody.source();
                        
                        while (!source.exhausted()) {
                            // 读取一行数据
                            String line = source.readUtf8Line();
                            
                            if (line == null) {
                                break;
                            }
                            
                            // 忽略空行
                            if (line.isEmpty()) {
                                continue;
                            }
                            
                            // 如果行以"data: "开头，处理JSON数据
                            if (line.startsWith("data: ")) {
                                String jsonData = line.substring(6);
                                
                                // 忽略结束标记 [DONE]
                                if ("[DONE]".equals(jsonData.trim())) {
                                    continue;
                                }
                                
                                try {
                                    JSONObject dataJson = new JSONObject(jsonData);
                                    
                                    // 检查是否存在 choices 数组
                                    if (dataJson.has("choices") && !dataJson.isNull("choices")) {
                                        JSONArray choices = dataJson.getJSONArray("choices");
                                        
                                        if (choices.length() > 0) {
                                            JSONObject choice = choices.getJSONObject(0);
                                            
                                            // 获取增量内容
                                            if (choice.has("delta") && !choice.isNull("delta")) {
                                                JSONObject delta = choice.getJSONObject("delta");
                                                
                                                if (delta.has("content") && !delta.isNull("content")) {
                                                    String content = delta.getString("content");
                                                    fullResponse.append(content);
                                                    
                                                    // 在主线程中回调部分响应
                                                    final String partialContent = content;
                                                    new Handler(Looper.getMainLooper()).post(() -> {
                                                        callback.onPartialResponse(partialContent);
                                                    });
                                                }
                                            }
                                        }
                                    }
                                } catch (JSONException e) {
                                    Log.e(TAG, "解析流式响应JSON失败", e);
                                    // 记录错误但继续处理
                                }
                            }
                        }
                        
                        // 处理完毕，回调完整响应
                        final String completeResponse = fullResponse.toString();
                        new Handler(Looper.getMainLooper()).post(() -> {
                            callback.onComplete(completeResponse);
                        });
                        
                    } catch (IOException e) {
                        Log.e(TAG, "读取流式响应失败", e);
                        new Handler(Looper.getMainLooper()).post(() -> {
                            callback.onError("读取响应失败: " + e.getMessage());
                        });
                    }
                }
            });
            
        } catch (JSONException e) {
            Log.e(TAG, "创建聊天请求JSON失败", e);
            callback.onError("创建请求参数失败: " + e.getMessage());
        }
    }

    /**
     * 添加设备 - 兼容DeviceListActivity中的调用
     * 
     * @param device_name 设备名称 (必填)
     * @param device_type 设备类型 (选填)
     * @param device_info 设备附加信息 (选填)
     * @param device_web 设备Web页面地址 (选填)
     * @param status 设备状态 (选填)
     * @param callback 回调接口
     */
    public void addDevice(String device_name, String device_type, 
                         String device_info, String device_web,
                         String status, ApiCallback callback) {
        // 自动生成设备ID
        String device_id = "DEV" + (1000 + (int)(Math.random() * 9000));
        // 调用完整版方法，将null作为image参数传递
        addDevice(device_id, device_name, device_type, device_info, device_web, null, status, callback);
    }



} 